package com.seecen.HJM.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.seecen.HJM.constant.JwtClaimsConstant;
import com.seecen.HJM.constant.MessageConstant;
import com.seecen.HJM.enumeration.LikeStatusEnum;
import com.seecen.HJM.enumeration.RoleEnum;
import com.seecen.HJM.mapper.ArtistMapper;
import com.seecen.HJM.mapper.UserFavoriteMapper;
import com.seecen.HJM.model.dto.ArtistAddDTO;
import com.seecen.HJM.model.dto.ArtistDTO;
import com.seecen.HJM.model.dto.ArtistUpdateDTO;
import com.seecen.HJM.model.entity.Artist;
import com.seecen.HJM.model.entity.UserFavorite;
import com.seecen.HJM.model.vo.ArtistDetailVO;
import com.seecen.HJM.model.vo.ArtistNameVo;
import com.seecen.HJM.model.vo.ArtistVo;
import com.seecen.HJM.model.vo.SongVo;
import com.seecen.HJM.result.DataVo;
import com.seecen.HJM.result.PageResult;
import com.seecen.HJM.service.ArtistService;
import com.seecen.HJM.service.MinioService;
import com.seecen.HJM.util.JwtUtil;
import com.seecen.HJM.util.TypeConversionUtil;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author jiachen
 * @description 针对表【tb_artist】的数据库操作Service实现
 * @createDate 2025-09-26 14:09:01
 *
 */
@Service
@Slf4j
@CacheConfig(cacheNames = "artistCache")
public class ArtistServiceImpl extends ServiceImpl<ArtistMapper, Artist>
        implements ArtistService {
    // 地区映射：前端聚合值 -> 数据库实际地区（支持模糊匹配）
    private static final Map<String, String[]> REGION_MAPPING = new HashMap<>() {{
        put("中国", new String[]{"中国"});          // 匹配数据库中含"中国"的地区（如中国内地、中国香港等）
        put("日韩", new String[]{"日本", "韩国"});  // 匹配日本、韩国
        put("欧美", new String[]{
                "美国", "荷兰", "英国", "法国", "德国", "意大利", "加拿大",
                "瑞士", "奥地利", "丹麦", "克罗地亚", "挪威", "瑞典", "芬兰", // 补充欧洲国家
                "澳大利亚", "新西兰" // 补充大洋洲欧美文化圈国家
        });
    }};
    //  定义所有主要地区的关键词（用于排除）
    private static final Set<String> MAIN_REGIONS = new HashSet<>();

    static {
        // 合并中国、日韩、欧美的所有关键词到一个集合(强转为list才可以add)
        MAIN_REGIONS.addAll(Arrays.asList(REGION_MAPPING.get("中国")));
        // 提取"日韩"的关键词（复用 REGION_MAPPING 配置，无需再写 new String[]{"日本","韩国"}）
        MAIN_REGIONS.addAll(Arrays.asList(REGION_MAPPING.get("日韩")));
        // 提取"欧美"的关键词（复用 REGION_MAPPING 配置，无需重复写欧美国家列表）
        MAIN_REGIONS.addAll(Arrays.asList(REGION_MAPPING.get("欧美")));
    }

    @Autowired
    private ArtistMapper artistMapper;
    @Autowired
    private UserFavoriteMapper userFavoriteMapper;
    @Autowired
    private MinioService minioService;

    //获取歌手名称列表
    @Override
    public DataVo<List<ArtistNameVo>> getAllArtistNames() {
        List<Artist> artists = artistMapper.selectList(new QueryWrapper<Artist>().orderByDesc("id"));
        if (artists.isEmpty()) {
            return DataVo.success(MessageConstant.DATA_NOT_FOUND, null);
        }

        List<ArtistNameVo> artistNameVOList = artists.stream()
                .map(artist -> {
                    ArtistNameVo artistNameVO = new ArtistNameVo();
                    artistNameVO.setArtistId(artist.getId());
                    artistNameVO.setArtistName(artist.getName());
                    return artistNameVO;
                }).toList();

        return DataVo.success(artistNameVOList);
    }

    @Override
    @Cacheable(key = "#artistDTO.pageNum + '-' + #artistDTO.pageSize + '-' + #artistDTO.artistName + '-' + #artistDTO.gender + '-' + #artistDTO.area")
    public DataVo<PageResult<ArtistVo>> getAllArtists(ArtistDTO artistDTO) {
        // 分页查询
        Page<Artist> page = new Page<>(artistDTO.getPageNum(), artistDTO.getPageSize());
        QueryWrapper<Artist> queryWrapper = new QueryWrapper<>();

        // 1. 歌手名模糊查询（原逻辑正确，保留）
        if (Objects.nonNull(artistDTO.getArtistName()) && !artistDTO.getArtistName().trim().isEmpty()) {
            queryWrapper.like("name", artistDTO.getArtistName());

        }

        // 2. 性别查询（原逻辑正确，保留）
        Integer gender = artistDTO.getGender();
        if (Objects.nonNull(gender) && (gender == 0 || gender == 1 || gender == 2)) {
            queryWrapper.eq("gender", gender);
        }

        // 3. 地区查询（核心修改：area为空时不拼接条件）
        String area = artistDTO.getArea();
        if ("其他".equals(area)) {
            // 优化：用notIn+like批量排除，减少SQL条件数量（比循环and更高效）
            queryWrapper.notInSql("area",
                    "SELECT area FROM tb_artist WHERE " +
                            MAIN_REGIONS.stream().map(reg -> "area LIKE '%" + reg + "%'").collect(Collectors.joining(" OR "))
            );
        } else if (Objects.nonNull(area) && !area.trim().isEmpty()) { // 仅当area非空时处理
            String[] dbRegions = REGION_MAPPING.get(area);
            if (dbRegions != null && dbRegions.length > 0) {
                // 正确：拼接 OR LIKE 条件（原逻辑正确，保留）
                queryWrapper.and(qw -> {
                    for (String region : dbRegions) {
                        qw.or().like("area", region);
                    }
                });
            }
        }

        // 执行查询
        IPage<Artist> artistPage = artistMapper.selectPage(page, queryWrapper);
        if (artistPage.getRecords().isEmpty()) {
            return DataVo.success(MessageConstant.DATA_NOT_FOUND, new PageResult<>(0L, null));
        }

        // 转换为ArtistVo（原逻辑正确，保留）
        List<ArtistVo> artistVoList = artistPage.getRecords().stream()
                .map(artist -> {
                    ArtistVo artistVo = new ArtistVo();
                    // 关键日志：打印数据库查询到的name值
                    System.out.println("Artist ID: " + artist.getId() + ", 数据库name值: " + artist.getName());
                    BeanUtils.copyProperties(artist, artistVo);
                    artistVo.setArtistName(artist.getName());
                    System.out.println("赋值后ArtistVo.artistName: " + artistVo.getArtistName());
                    return artistVo;
                }).toList();

        return DataVo.success(new PageResult<>(artistPage.getTotal(), artistVoList));
    }
    @Override
    public DataVo<List<ArtistVo>> getRandomArtists() {
        QueryWrapper<Artist> queryWrapper = new QueryWrapper<>();
        queryWrapper.last("ORDER BY RAND() LIMIT 10");
        List<Artist> artistList = artistMapper.selectList(queryWrapper);
        if(artistList.isEmpty()){
            return DataVo.success(MessageConstant.DATA_NOT_FOUND,null);
        }
        List<ArtistVo> artistVoList = artistList.stream().map(artist -> {
            ArtistVo artistVo = new ArtistVo();
            BeanUtils.copyProperties(artist, artistVo);
            return artistVo;
        }).toList();
        return DataVo.success(artistVoList);
    }

    @Override
    @Cacheable(key = "#artistId")
    public DataVo<ArtistDetailVO> getArtistDetail(Long artistId, HttpServletRequest request) {
        ArtistDetailVO artistDetailVO = artistMapper.getArtistDetailById(artistId);
        //设置默认状态
        List<SongVo> songVoList =artistDetailVO.getSongs();
        for(SongVo songVo : songVoList){
            songVo.setLikeStatus(LikeStatusEnum.DEFAULT.getId());
        }
        //获取请求头中token
        String token = request.getHeader("Authorization");
        if (token != null && token.startsWith("Bearer ")) {
            token = token.substring(7); // 去掉 "Bearer " 前缀
        }
        Map<String, Object> map = null;
        if (token != null && !token.isEmpty()) {
            map = JwtUtil.parseToken(token);
        }
        if(map!=null){
            String role = (String) map.get(JwtClaimsConstant.ROLE);
            if(role.equals(RoleEnum.USER.getRole())){
                Object userObj = map.get(JwtClaimsConstant.USER_ID);
                Long userId = TypeConversionUtil.toLong(userObj);
                //获取用户收藏的歌曲
                QueryWrapper<UserFavorite> userFavoriteQueryWrapper = new QueryWrapper<>();
                userFavoriteQueryWrapper.eq("user_id", userId);
                userFavoriteQueryWrapper.eq("type",0);
                List<UserFavorite> favoriteSongs = userFavoriteMapper.selectList(userFavoriteQueryWrapper);
                //获取用户收藏的歌曲id
                Set<Long> favoriteSongIds = favoriteSongs.stream()
                        .map(UserFavorite::getSongId)
                        .collect(Collectors.toSet());
                //检查更新状态
                for (SongVo songVo : songVoList) {
                    if (favoriteSongIds.contains(songVo.getSongId())){
                        songVo.setLikeStatus(LikeStatusEnum.LIKE.getId());
                    }
                }
            }
        }
        //设置歌曲列表
        artistDetailVO.setSongs(songVoList);
        return DataVo.success(artistDetailVO);
    }
    // 获取所有歌手列表 用于管理端获取信息

    @Override
    @Cacheable(key = "#artistDTO.pageNum + '-' + #artistDTO.pageSize + '-' + #artistDTO.artistName + '-' + #artistDTO.gender + '-' + #artistDTO.area + '-admin'")
    public DataVo<PageResult<Artist>> getAllArtistsAndDetail(ArtistDTO artistDTO) {
        // 分页查询
        Page<Artist> page = new Page<>(artistDTO.getPageNum(), artistDTO.getPageSize());
        QueryWrapper<Artist> queryWrapper = new QueryWrapper<>();
        // 1. 歌手名模糊查询（原逻辑正确，保留）
        if (Objects.nonNull(artistDTO.getArtistName()) && !artistDTO.getArtistName().trim().isEmpty()) {
            queryWrapper.like("name", artistDTO.getArtistName());
        }

        // 2. 性别查询（原逻辑正确，保留）
        Integer gender = artistDTO.getGender();
        if (Objects.nonNull(gender) && (gender == 0 || gender == 1 || gender == 2)) {
            queryWrapper.eq("gender", gender);
        }

        // 3. 地区查询（核心修改：area为空时不拼接条件）
        String area = artistDTO.getArea();
        if ("其他".equals(area)) {
            // 优化：用notIn+like批量排除，减少SQL条件数量（比循环and更高效）
            queryWrapper.notInSql("area",
                    "SELECT area FROM tb_artist WHERE " +
                            MAIN_REGIONS.stream().map(reg -> "area LIKE '%" + reg + "%'").collect(Collectors.joining(" OR "))
            );
        } else if (Objects.nonNull(area) && !area.trim().isEmpty()) { // 仅当area非空时处理
            String[] dbRegions = REGION_MAPPING.get(area);
            if (dbRegions != null && dbRegions.length > 0) {
                // 正确：拼接 OR LIKE 条件（原逻辑正确，保留）
                queryWrapper.and(qw -> {
                    for (String region : dbRegions) {
                        qw.or().like("area", region);
                    }
                });
            }
        }

        // 倒序排序
        queryWrapper.orderByDesc("id");

        IPage<Artist> artistPage = artistMapper.selectPage(page, queryWrapper);
        if (artistPage.getRecords().size() == 0) {
            return DataVo.success(MessageConstant.DATA_NOT_FOUND, new PageResult<>(0L, null));
        }

        return DataVo.success(new PageResult<>(artistPage.getTotal(), artistPage.getRecords()));
    }
    //添加歌手
    @Override
    @CacheEvict(cacheNames = "artistCache", allEntries = true)
    public DataVo addArtist(ArtistAddDTO artistAddDTO) {
        QueryWrapper<Artist> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", artistAddDTO.getName());
        if (artistMapper.selectCount(queryWrapper) > 0) {
            return DataVo.error(MessageConstant.ARTIST + MessageConstant.ALREADY_EXISTS);
        }

        Artist artist = new Artist();
        BeanUtils.copyProperties(artistAddDTO, artist);
        artistMapper.insert(artist);

        return DataVo.success(MessageConstant.ADD + MessageConstant.SUCCESS);
    }

    //更新歌手
    @Override
    @CacheEvict(cacheNames = "artistCache", allEntries = true)
    public DataVo updateArtist(ArtistUpdateDTO artistUpdateDTO) {
        Long artistId = artistUpdateDTO.getId();

        Artist artistByArtistName = artistMapper.selectOne(new QueryWrapper<Artist>().eq("name", artistUpdateDTO.getName()));
        if (artistByArtistName != null && !artistByArtistName.getId().equals(artistId)) {
            return DataVo.error(MessageConstant.ARTIST + MessageConstant.ALREADY_EXISTS);
        }
        // 校验出生日期是否为未来时间
        LocalDate birthDate = artistUpdateDTO.getBirth();
        if (birthDate != null) {
            LocalDate currentDate = LocalDate.now();
            if (birthDate.isAfter(currentDate)) {
                return DataVo.error("出生日期不能为当前时间之后");
            }
        }
        Artist artist = new Artist();
        BeanUtils.copyProperties(artistUpdateDTO, artist);
        if (artistMapper.updateById(artist) == 0) {
            return DataVo.error(MessageConstant.UPDATE + MessageConstant.FAILED);
        }
        System.out.println();
        return DataVo.success(MessageConstant.UPDATE + MessageConstant.SUCCESS);
    }

    //更新歌手头像
    @Override
    @CacheEvict(cacheNames = "artistCache", allEntries = true)
    public DataVo updateArtistAvatar(Long artistId, String avatar) {
        Artist artist = artistMapper.selectById(artistId);
        String avatarUrl = artist.getAvatar();
        if (avatarUrl != null && !avatarUrl.isEmpty()) {
            minioService.deleteFile(avatarUrl);
        }

        artist.setAvatar(avatar);
        if (artistMapper.updateById(artist) == 0) {
            return DataVo.error(MessageConstant.UPDATE + MessageConstant.FAILED);
        }

        return DataVo.success(MessageConstant.UPDATE + MessageConstant.SUCCESS);
    }

    //删除歌手
    @Override
    @CacheEvict(cacheNames = "artistCache", allEntries = true)
    public DataVo deleteArtist(Long artistId) {
        // 1. 查询歌手信息，获取头像 URL
        Artist artist = artistMapper.selectById(artistId);
        if (artist == null) {
            return DataVo.error(MessageConstant.ARTIST + MessageConstant.NOT_FOUND);
        }
        String avatarUrl = artist.getAvatar();

        // 2. 先删除 MinIO 里的头像文件
        if (avatarUrl != null && !avatarUrl.isEmpty()) {
            minioService.deleteFile(avatarUrl);
        }

        // 3. 删除数据库中的歌手信息
        if (artistMapper.deleteById(artistId) == 0) {
            return DataVo.error(MessageConstant.DELETE + MessageConstant.FAILED);
        }

        return DataVo.success(MessageConstant.DELETE + MessageConstant.SUCCESS);
    }

    //批量删除歌手
    @Override
    @CacheEvict(cacheNames = {"artistCache", "songCache"}, allEntries = true)
    public DataVo deleteArtists(List<Long> artistIds) {
        // 1. 查询歌手信息，获取头像 URL 列表
        List<Artist> artists = artistMapper.selectByIds(artistIds);
        List<String> avatarUrlList = artists.stream()
                .map(Artist::getAvatar)
                .filter(avatarUrl -> avatarUrl != null && !avatarUrl.isEmpty())
                .toList();

        // 2. 先删除 MinIO 里的头像文件
        for (String avatarUrl : avatarUrlList) {
            minioService.deleteFile(avatarUrl);
        }

        // 3. 删除数据库中的歌手信息
        if (artistMapper.deleteByIds(artistIds) == 0) {
            return DataVo.error(MessageConstant.DELETE + MessageConstant.FAILED);
        }

        return DataVo.success(MessageConstant.DELETE + MessageConstant.SUCCESS);
    }

}




